package com.qs.commontools.utils.file;

import com.qs.commontools.common.service.ImgService;

import java.awt.*;
import java.io.File;
import java.io.Serializable;

/**
 * 水印制作工具
 * @author qiusuo
 * @since 2021-11-15
 */
public class WaterMarkTool  implements Serializable {
    private static final long serialVersionUID = 8437848164662237037L;

    /**
     * 水印文本
     */
    private String text;

    /**
     * 原始图片文件对象
     */
    private File srcImg;

    /**
     * 旋转角度
     */
    private Integer angle;

    /**
     * 水印文本颜色
     */
    private Color color;

    /**
     * 字体
     */
    private Font font;

    /**
     * 水印文字透明度
     */
    private Float opacity;

    /**
     * 水印横向位置
     */
    private Integer horizontalPosition;

    /**
     * 横向间隔
     */
    private Integer horizontalInterval;

    /**
     * 水平水印个数
     */
    private Integer horizontalNum;

    /**
     * 水印纵向位置
     */
    private Integer verticalPosition;

    /**
     * 纵向间隔
     */
    private Integer verticalInterval;

    /**
     * 垂直水印个数
     */
    private Integer verticalNum;

    /**
     * 文本是否是单一水印
     */
    private Boolean single;

    /**
     * 水印图片
     */
    private File icon;

    /**
     * 水印图片横向坐标位置
     */
    private Integer iconPositionX;

    /**
     * 水印图片纵向坐标位置
     */
    private Integer iconPositionY;

    /**
     * 水印图片宽度，默认最宽为80像素的等比例缩小
     */
    private Integer iconWidth;

    /**
     * 水印图片高度，默认最高为80像素的等比例缩小
     */
    private Integer iconHeight;

    /**
     * 水印旋转角度
     */
    private Integer iconAngle;

    /**
     * 水印图片的透明度
     */
    private Float iconOpacity;

    private WaterMarkTool() {
    }

    /**
     * 获得实例对象初始化。
     *
     * @return 水印工具实例
     */
    public static WaterMarkTool getInstance() {
        WaterMarkTool tool = new WaterMarkTool();
        // 设置默认文本
        tool.setText("水印文本");
        // 设置默认水印文本颜色
        tool.setColor(Color.RED);
        // 设置默认字体
        tool.setFont(new Font("宋体", Font.BOLD, 18));
        // 设置默认旋转角度
        tool.setAngle(0);
        // 设置默认透明度
        tool.setOpacity(0.5f);
        // 设置水印默认起始位置（X轴）
        tool.setHorizontalPosition(0);
        // 设置水印默认起始位置（Y轴）
        tool.setVerticalPosition(18);
        // 设置默认是单一水印
        tool.setSingle(true);
        // 设置横向文本之间的默认间隔
        tool.setHorizontalInterval(10);
        // 设置纵向文本之间的默认间隔
        tool.setVerticalInterval(10);

        return tool;
    }

    /**
     * 获得序列化号。
     *
     * @return 序列号
     */
    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    /**
     * 获得水印文本。
     *
     * @return 水印文本
     */
    public String getText() {
        return text;
    }

    /**
     * 设置要添加的水印文本。
     *
     * @param text 水印文本
     */
    public void setText(String text) {
        this.text = text;
    }

    /**
     * 获得被添加水印的图片文件对象。
     *
     * @return 图片对象
     */
    public File getSrcImg() {
        return srcImg;
    }

    /**
     * 设置被添加水印的图片。
     *
     * @param srcImgPath 原图片路径
     */
    public void setSrcImg(String srcImgPath) {
        this.srcImg = new File(srcImgPath);
    }

    /**
     * 设置被添加水印的图片。
     *
     * @param srcImgFile 原图片文件对象
     */
    public void setSrcImg(File srcImgFile) {
        this.srcImg = srcImgFile;
    }

    /**
     * 获得水印旋转角度，默认不旋转为0。
     *
     * @return 旋转角度
     */
    public Integer getAngle() {
        return angle;
    }

    /**
     * 设置水印旋转角度，默认不旋转为0。
     *
     * @param angle 旋转角度
     */
    public void setAngle(Integer angle) {
        this.angle = angle;
    }

    /**
     * 获得水印文本的颜色，默认红色。
     *
     * @return 水印文本的颜色
     */
    public Color getColor() {
        return color;
    }

    /**
     * 设置水印文本的颜色，默认红色。
     *
     * @param color 水印文本的颜色
     */
    public void setColor(Color color) {
        this.color = color;
    }

    /**
     * 获得水印文本的字体，默认宋体加粗18号字体。
     *
     * @return 水印文本的字体
     */
    public Font getFont() {
        return font;
    }

    /**
     * 设置水印文本的字体。
     * <br>可通过：new Font("宋体", Font.BOLD, 18)设置
     *
     * @param font 水印文本的字体
     */
    public void setFont(Font font) {
        this.font = font;
    }

    /**
     * 获得水印透明度，0～1f。
     *
     * @return 水印文本透明度
     */
    public Float getOpacity() {
        return opacity;
    }

    /**
     * 设置水印透明度，0～1f。
     * <br>0表示全透明，1表示不透明
     *
     * @param opacity 水印文本透明度
     */
    public void setOpacity(Float opacity) {
        this.opacity = opacity;
    }

    /**
     * 获得水印起始位置（X轴）。
     * <br>默认距离左顶点0
     *
     * @return 水印起始位置
     */
    public Integer getHorizontalPosition() {
        return horizontalPosition;
    }

    /**
     * 设置水印起始位置（X轴）。
     * <br>默认距离左顶点0
     *
     * @param horizontalPosition 水印起始位置
     */
    public void setHorizontalPosition(Integer horizontalPosition) {
        this.horizontalPosition = horizontalPosition;
    }

    /**
     * 获得横向水印与水印之间的间隔。
     * <br>默认10
     *
     * @return 间隔
     */
    public Integer getHorizontalInterval() {
        return horizontalInterval;
    }

    /**
     * 设置横向水印与水印之间的间隔。
     * <br>默认10
     *
     * @param horizontalInterval 间隔
     */
    public void setHorizontalInterval(Integer horizontalInterval) {
        this.horizontalInterval = horizontalInterval;
    }

    /**
     * 获得水平方向水印的个数。
     *
     * @return 水印个数
     */
    public Integer getHorizontalNum() {
        return horizontalNum;
    }

    /**
     * 设置水平方向水印的个数。
     *
     * @param horizontalNum 水印个数
     */
    public void setHorizontalNum(Integer horizontalNum) {
        if (horizontalNum > 1) {
            this.single = false;
        }
        this.horizontalNum = horizontalNum;
    }

    /**
     * 获得垂直方向水印默认起始位置（Y轴）。
     * <br>默认离左上角18
     *
     * @return 垂直方向水印起始位置
     */
    public Integer getVerticalPosition() {
        return verticalPosition;
    }

    /**
     * 设置垂直方向水印默认起始位置（Y轴）。
     * <br>默认离左上角18
     *
     * @param verticalPosition 垂直方向水印起始位置
     */
    public void setVerticalPosition(Integer verticalPosition) {
        this.verticalPosition = verticalPosition;
    }

    /**
     * 获得垂直方向水印之间的间隔。
     * <br> 默认是10。
     *
     * @return 水印之间的间隔
     */
    public Integer getVerticalInterval() {
        return verticalInterval;
    }

    /**
     * 设置垂直方向水印之间的间隔。
     * <br>默认是10。
     *
     * @param verticalInterval 水印之间的间隔
     */
    public void setVerticalInterval(Integer verticalInterval) {
        this.verticalInterval = verticalInterval;
    }

    /**
     * 获得垂直方向的水印个数。
     *
     * @return 垂直方向水印个数
     */
    public Integer getVerticalNum() {
        return verticalNum;
    }

    /**
     * 设置垂直方向水印的个数。
     *
     * @param verticalNum 垂直方向水印个数
     */
    public void setVerticalNum(Integer verticalNum) {
        if (verticalNum > 1) {
            this.single = false;
        }
        this.verticalNum = verticalNum;
    }

    /**
     * 或是是否绘制单一水印。
     *
     * @return true 仅绘制一个水印， false根据算法绘制多个水印
     */
    public Boolean getSingle() {
        return single;
    }

    /**
     * 设置是否绘制单一水印。
     *
     * @param single true 仅绘制一个水印， false根据算法绘制多个水印
     */
    public void setSingle(Boolean single) {
        this.single = single;
    }

    /**
     * 获得要添加的水印图片文件。
     *
     * @return 水印图片
     */
    public File getIcon() {
        return icon;
    }

    /**
     * 设置想要添加的水印图片。
     *
     * @param imgPath 水印图片的地址
     */
    public void setIcon(String imgPath) {
        setIcon(new File(imgPath));
    }

    /**
     * 设置想要添加的水印图片。
     *
     * @param icon 水印图片的File对象
     */
    public void setIcon(File icon) {
        this.icon = icon;
    }

    /**
     * 获得要在图片上添加图片水印横向坐标的位置。
     *
     * @return x轴位置
     */
    public Integer getIconPositionX() {
        return iconPositionX;
    }

    /**
     * 设置要在图片上添加图片水印横向坐标的位置。
     *
     * @param iconPositionX x轴位置
     */
    public void setIconPositionX(Integer iconPositionX) {
        this.iconPositionX = iconPositionX;
    }

    /**
     * 获得要在图片上添加图片水印纵向坐标的位置。
     *
     * @return y轴位置
     */
    public Integer getIconPositionY() {
        return iconPositionY;
    }

    /**
     * 设置要在图片上添加图片水印纵向坐标的位置。
     *
     * @param iconPositionY y轴位置
     */
    public void setIconPositionY(Integer iconPositionY) {
        this.iconPositionY = iconPositionY;
    }

    /**
     * 获得在图片上添加图片水印的图片宽度。
     * <br>默认宽为80像素的等比例缩小
     *
     * @return 图片水印的图片宽度
     */
    public Integer getIconWidth() {
        return iconWidth;
    }

    /**
     * 设置在图片上添加图片水印的图片宽度。
     * <br>默认宽为80像素的等比例缩小
     *
     * @param iconWidth 图片水印的图片宽度
     */
    public void setIconWidth(Integer iconWidth) {
        this.iconWidth = iconWidth;
    }

    /**
     * 获得在图片上添加图片水印的图片高度。
     * <br>默认高为80像素的等比例缩小
     *
     * @return 图片水印的图片高度
     */
    public Integer getIconHeight() {
        return iconHeight;
    }

    /**
     * 设置在图片上添加图片水印的图片高度。
     * <br>默认高为80像素的等比例缩小
     *
     * @param iconHeight  图片水印的图片高度
     */
    public void setIconHeight(Integer iconHeight) {
        this.iconHeight = iconHeight;
    }

    /**
     * 获得在图片上添加图片水印的图片旋转角度。
     *
     * @return 图片旋转角度
     */
    public Integer getIconAngle() {
        return iconAngle;
    }

    /**
     * 设置在图片上添加图片水印的图片旋转角度。
     *
     * @param iconAngle  图片旋转角度
     */
    public void setIconAngle(Integer iconAngle) {
        this.iconAngle = iconAngle;
    }

    /**
     * 获得在图片上添加图片水印的图片透明度。
     *
     * @return 图片透明度
     */
    public Float getIconOpacity() {
        return iconOpacity;
    }

    /**
     * 设置在图片上添加图片水印的图片透明度。
     *
     * @param iconOpacity  图片透明度
     */
    public void setIconOpacity(Float iconOpacity) {
        this.iconOpacity = iconOpacity;
    }

    /**
     * 执行添加图片水印的操作，依赖于之前的所有设置。
     *
     * @throws Exception 水印添加异常
     * @return 添加完成后的图片字节数组
     */
    public byte[] create() throws Exception {
        ImgService imgService = ImgService.getInstance();
        return imgService.waterMark(this);
    }
}
